package lockDemo;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Ajie
 * @date 8/10/21
 * @function
 * lock.tryLock(）
 *线程Thread - 0等待获取锁
 *线程Thread - 0获取锁成功
 *线程Thread - 1等待获取锁
 *线程Thread - 1获取锁失败 !!!直接返回。不阻塞。
 *线程Thread - 0释放锁
 *
 * <p>
 * lock.tryLock(4000, TimeUnit.MILLISECONDS)
 * 线程Thread-0等待获取锁
 * 线程Thread-1等待获取锁 //阻塞
 * 线程Thread-0获取锁成功
 * 线程Thread-0释放锁
 * 线程Thread-1获取锁成功 //再等待时间内获得了锁。
 * 线程Thread-1释放锁
 */
public class TryLockDemo {
    //实例化Lock对象
    Lock lock = new ReentrantLock();

    /**
     * @param args
     */
    public static void main(String[] args) {
        //实例化本类对象，目的是调用runThread方法
        TryLockDemo tl = new TryLockDemo();
        //匿名对象创建线程1，并重写run方法，启动线程
        new Thread() {
            public void run() {

                tl.runThread(Thread.currentThread());
            }
        }.start();
        //匿名对象创建线程2，并重写run方法，启动线程
        new Thread() {
            public void run() {

                tl.runThread(Thread.currentThread());
            }
        }.start();


    }

    //线程共同调用方法
    public void runThread(Thread t) {
        //lock对象调用trylock()方法尝试获取锁
        try {
            System.out.println("线程" + t.getName() + "等待获取锁");
//            if (lock.tryLock()) { //没有指定时间。
            if (lock.tryLock(4000, TimeUnit.MILLISECONDS)) {//TODO 指定时间
                //获锁成功代码段
                System.out.println("线程" + t.getName() + "获取锁成功");
                try {
                    //执行的代码
                    Thread.sleep(3000);
                } catch (Exception e) {
                    //异常处理内容，比如中断异常，需要恢复等
                } finally {
                    //获取锁成功之后，一定记住加finally并unlock()方法,释放锁
                    System.out.println("线程" + t.getName() + "释放锁");
                    lock.unlock();
                }
            } else {
                //获锁失败代码段
                //具体获取锁失败的回复响应
                System.out.println("线程" + t.getName() + "获取锁失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
